package com.example;

import com.example.observer.Observable;
import com.example.observer.Observer;
import com.example.state.HasQuarterState;
import com.example.state.NoQuarterState;
import com.example.state.SoldOutState;
import com.example.state.SoldState;
import com.example.state.State;

import java.rmi.RemoteException;
import java.util.ArrayList;
import java.util.List;

/**
 * 贩卖机
 */
public class Machine implements Observable {
    // 贩卖机信息
    private final State noQuarterState;
    private final State hasQuarterState;
    private final State soldOutState;
    private final State soldState;

    // 观察者列表
    List<Observer> observerList = new ArrayList<>();
    // 贩卖机当前的状态
    private State state;
    // 糖果的数量
    private int count;

    public Machine(int gumballCount) {
        noQuarterState = new NoQuarterState(this);
        hasQuarterState = new HasQuarterState(this);
        soldOutState = new SoldOutState(this);
        soldState = new SoldState(this);

        // 根据给定的糖果的数量，决定贩卖机的初始状态
        this.count = gumballCount;
        if (gumballCount > 0) {
            state = noQuarterState;
        } else {
            state = soldOutState;
        }
    }

    public void insertQuarter() {
        state.insertQuarter();
    }

    public void ejectQuarter() {
        state.ejectQuarter();
    }

    public void turnCrank() {
        state.turnCrank();
    }

    public void dispense() {
        state.dispense();
    }

    public State getHasQuarterState() {
        return hasQuarterState;
    }

    public State getNoQuarterState() {
        return noQuarterState;
    }

    public State getSoldOutState() {
        return soldOutState;
    }

    public State getSoldState() {
        return soldState;
    }

    public void releaseBall() {
        if (count > 0) {
            count--;
        }
    }

    @Override
    public void notifyObservers() throws RemoteException {
        // 封装信息
        MachineInfo info = new MachineInfo();
        info.setState(state.toString());
        info.setCount(count);

        for (Observer observer : observerList) {
            observer.update(info);
        }
    }

    @Override
    public void attach(Observer observer) {
        observerList.add(observer);
    }

    @Override
    public void detach(Observer observer) {
        observerList.remove(observer);
    }

    public int getCount() {
        return count;
    }

    public State getState() {
        return state;
    }

    public void setState(State state) {
        this.state = state;
    }

    public String getLocation() {
        return "not defined!";
    }
}
